﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;  //MD5密码加密   
using System.Data.SqlClient;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
using System.Collections;
using System.Drawing;
using System.Runtime.InteropServices;

namespace IAP_Update
{
    class GlobalMethods
    {
        public static byte _fillChar = 0;//the fill character
        //防止窗体重复打开  
        public static ArrayList gFormList = new ArrayList();


        #region"指定一个唯一的窗体标识，再轮寻这个标识"
        /// <summary>
        ///要使窗体不被重复打开，首先在MainForm中new一个static的FormList，
        ///然后在打开窗体时在FromList中轮寻，找到与此类型相一致的就Activate()，
        ///否则就new一个新的form，并且加到FormList中，在form退出时千万别忘记把
        ///自己从FormList中退出来，就是用Remove（this）就可以了      
        /// </summary>      
        public static bool CheckFormActivate(string Name)
        {
            try
            {
                foreach (Form oformlist in gFormList)
                    if (oformlist.Name.Equals(Name))
                    {
                        oformlist.Activate();
                        return false;
                    }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return true;
            }
        }
        #endregion

        #region"配置参数"
        /// <summary>
        /// 获取配置参数
        /// </summary>
        public void GetConfigParm()
        {
            string cfgINI = Application.StartupPath + IniFile.FILE_NAME;
            if (!File.Exists(cfgINI))
            {
                throw new System.Exception("GlobalMethods->CheckFormActivate(),文件路径不存在！");
                //return ;
            }
            try
            {
                IniFile ini = new IniFile(cfgINI);
                Uart.gUartInfo.portName = ini.IniReadValue("Serial", "port");//端口
                Uart.gUartInfo.bandRate = ini.IniReadValue_Int("Serial", "baudrate"); //波特率
                Uart.gUartInfo.dataBits = Convert.ToByte(ini.IniReadValue_Int("Serial", "databits")); //数据位
                Uart.gUartInfo.parity = ini.IniReadValue("Serial", "parity"); //校验位
                Uart.gUartInfo.stopBits = ini.IniReadValue("Serial", "stopbits"); //停止位
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }
        #endregion 获取配置参数

        #region 文件流方式读写文件
        /// <summary>
        /// 读取文件
        /// </summary>
        public static void ReadFromTxtFile(string FilePath, ListView ListView)
        {
            if (string.IsNullOrEmpty(FilePath))
            {
                //throw new System.ArgumentException("GlobalMethods->ReadFromTxtFile(),文件路径不能为空。");
                return;
            }
            string tString = null;
            //获取文件扩展名
            GlobalVariables.FileExtensionName = FilePath.Substring(FilePath.LastIndexOf(".") + 1, 3);
            //获取文件名
            GlobalVariables.FileName = FilePath.Substring(FilePath.LastIndexOf('\\') + 1, FilePath.Length - FilePath.LastIndexOf('\\') - 1);
            if (GlobalVariables.FileExtensionName != "txt" && GlobalVariables.FileExtensionName != "TXT")
            {
                //MessageBox.Show("只能打开或输入扩展名为.txt的文件", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                throw new System.Exception("GlobalMethods->ReadFromTxtFile(),只能打开扩展名为.txt的文件！");
                //return;
            }

            FileStream fs = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None);
            StreamReader sr = new StreamReader(fs);
            try
            {
                byte tIndex = 0;
                sr.BaseStream.Seek(0, SeekOrigin.Begin);
                tString = sr.ReadLine();
                while (tString != null)
                {
                    tIndex++;//索引号
                    string[] tStrArr = tString.Split(':');
                    if (tStrArr.Length != 2)//异常处理
                    {
                        throw new System.Exception("GlobalMethods->ReadFromTxtFile(),tStrArr.Length != 2");
                        //return;
                    }
                    //第三步：控件中显示 
                    ListViewItem lv = new ListViewItem();
                    lv.SubItems[0].Text = tIndex.ToString();
                    lv.SubItems.Add(tStrArr[0]);//在listView控件中添加命令名称
                    lv.SubItems.Add(tStrArr[1]);//在listView控件中添加命令帧
                    ListView.Items.Add(lv);//向listView控件中追加新添加的各列
                    tString = sr.ReadLine();
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("读取文件失败！", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Error);             
                Console.WriteLine(ex.Message.ToString());
            }
            finally
            {
                sr.Close();
                sr.Dispose();
                fs.Close();
                fs.Dispose();
            }
        }

        /// <summary>
        /// 写文件
        /// </summary>
        public static void WriteToTxtFile(string FilePath, ListView ListView)
        {
            string tString = null;
            //写文件
            if (string.IsNullOrEmpty(FilePath))
            {
                throw new System.ArgumentException("GlobalMethods->WriteToTxtFile(),文件路径不能为空。");
            }
            //获取文件扩展名
            GlobalVariables.FileExtensionName = FilePath.Substring(FilePath.LastIndexOf(".") + 1, 3);
            //获取文件名
            GlobalVariables.FileName = FilePath.Substring(FilePath.LastIndexOf('\\') + 1, FilePath.Length - FilePath.LastIndexOf('\\') - 1);
            if (GlobalVariables.FileExtensionName != "txt" && GlobalVariables.FileExtensionName != "TXT")
            {
                throw new System.Exception("GlobalMethods->WriteToTxtFile(),只能打开扩展名为.txt的文件！");
                //MessageBox.Show("只能打开或输入扩展名为.txt的文件", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //return;
            }

            for (int i = 0; i < ListView.Items.Count; i++)
            {
                //listview.Items[行].SubItems[列].Text 
                //tString += listView1.FocusedItem.SubItems[1].Text +":"+ listView1.FocusedItem.SubItems[2].Text;
                tString += ListView.Items[i].SubItems[1].Text + ":" + ListView.Items[i].SubItems[2].Text + Environment.NewLine;
            }
            FileStream fs = new FileStream(FilePath, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            try
            {
                sw.Flush();
                sw.WriteLine(tString);
                sw.Flush();
            }
            catch (Exception ex)
            {
                //MessageBox.Show("文件写入失败！", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Console.WriteLine(ex.Message.ToString());
            }
            finally
            {
                sw.Close();
                sw.Dispose();
                fs.Close();
                fs.Dispose();
            }
        }
        #endregion  文件流方式读写文件

        ////////////////////////////////////////////////////////////////
        /// <summary>
        /// 将文件内容读入byte[]
        /// </summary>
        /// <param name="fullFile">包含完整路径的文件</param>
        /// <returns></returns>
        public static byte[] ReadFileToBytes(string fullFile)
        {
            byte[] bytes = null;
            FileStream fs = null;
            BinaryReader br = null;
            try
            {
                //判断文件是否已经存在
                if (!File.Exists(fullFile))
                {
                    MessageBox.Show("文件不存在！", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return null;
                }
                //获取文件扩展名
                string tFileExtenName = fullFile.Substring(fullFile.LastIndexOf(".") + 1, 3);
                //获取文件名
                //string tFileName = p_filepath.Substring(p_filepath.LastIndexOf('\\') + 1, p_filepath.Length - p_filepath.LastIndexOf('\\') - 1);
                if (tFileExtenName != "bin" && tFileExtenName != "BIN")
                {
                    MessageBox.Show("只能打开扩展名为.bin的文件", "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return null;
                }
                fs = new FileStream(fullFile, FileMode.Open, FileAccess.Read);
                br = new BinaryReader(fs);
                //int BytesSum = (int)fs.Length;//得到文件的字节总长
                int BytesSum = (int)(br.BaseStream.Length);
                br.BaseStream.Seek(0, SeekOrigin.Begin);
                bytes = br.ReadBytes(BytesSum); //将文件全部内容读作二进制流     
                //读取完毕，关闭              
                br.Close();
                fs.Close();
                br = null;
                fs = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show("在读取文件的过程中，发生了异常！" + ex.Message.ToString(), "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (br != null)
                    br.Close();
                if (fs != null)
                    fs.Close();
            }
            return bytes;
        }

        /// <summary>
        /// 将byte[]文件内容写入到指定文件
        /// </summary>
        /// <param name="bytes">文件内容</param>
        /// <param name="fullFile">包含完整路径的文件</param>
        public static void WriteBytesToFile(byte[] bytes, string fullFile)
        {
            FileStream fs = null;
            try
            {
                if (bytes == null)
                    return;
                FileInfo fileInfo = new FileInfo(fullFile);
                if (!Directory.Exists(fileInfo.Directory.FullName))
                {
                    Directory.CreateDirectory(fileInfo.Directory.FullName);
                }
                fs = new FileStream(fullFile, FileMode.Create);
                fs.Write(bytes, 0, bytes.Length);
                fs.Close();
                fs = null;

            }
            catch (Exception ex)
            {
                MessageBox.Show("在写入文件的过程中，发生了异常！" + ex.Message.ToString(), "系统信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }


        #region 通用方法
        /// <summary>
        /// 把ASCII转换为16进制
        /// </summary>
        public byte AscToHex(byte aChar)
        {
            if ((aChar >= 0x30) && (aChar <= 0x39))
                aChar -= 0x30;
            else if ((aChar >= 0x41) && (aChar <= 0x46))//大写字母
                aChar -= 0x37;
            else if ((aChar >= 0x61) && (aChar <= 0x66))//小写字母
                aChar -= 0x57;
            else aChar = 0xff;
            return aChar;
        }

        /// <summary>
        /// 把16进制转换为ASCII
        /// </summary>  
        public byte HexToAsc(byte aHex)
        {
            if ((aHex >= 0) && (aHex <= 9))
                aHex += 0x30;
            else if ((aHex >= 10) && (aHex <= 15))//A-F
                aHex += 0x37;
            else aHex = 0xff;
            return aHex;
        }

        /// <summary>       
        /// 结构体转byte[]
        /// </summary>
        public static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);//得到结构体的大小
            IntPtr buffer = Marshal.AllocHGlobal(size); //分配结构体大小的内存空间
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);//将结构体拷到分配好的内存空间
                byte[] bytes = new byte[size];//创建byte数组
                Marshal.Copy(buffer, bytes, 0, size); //从内存空间拷到byte数组
                return bytes;//返回byte数组
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return null;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);//释放内存空间
            }
        }

        /// <summary>         
        ///byte数组转换为结构体
        ///注：在win7中不能用
        /// </summary>
        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);//得到结构体的大小
            //byte数组长度小于结构体的大小
            if (size > bytes.Length)
            {
                throw new System.ArgumentException("GlobalMethods->BytesToStruct(),第二个形参为null。");
                //return null;
            }
            IntPtr buffer = Marshal.AllocHGlobal(size);//分配结构体大小的内存空间
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);//从byte数组拷到内存空间
                return Marshal.PtrToStructure(buffer, strcutType);//将分配好的内存空间拷到结构体
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return null;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);//释放内存空间
            }
        }

        /// <summary>
        /// convert string to byte array in Ascii with length is len      
        /// </summary>
        public static byte[] StringToBytes(string str, int len)
        {
            if (string.IsNullOrEmpty(str))
            {
                str = string.Empty;
            }

            byte[] result = new byte[len];
            byte[] strBytes = Encoding.Default.GetBytes(str);

            //copy the array converted into result, and fill the remaining bytes with 0
            for (int i = 0; i < len; i++)
                result[i] = ((i < strBytes.Length) ? strBytes[i] : _fillChar);
            return result;
        }

        /// <summary>
        /// convert string to byte array in Ascii with length is len      
        /// </summary>
        public static string BytesToString(byte[] arr)
        {
            if (arr == null) return null;
            return Encoding.Default.GetString(arr);
        }

        /// <summary>
        /// 整型转换成字节数组
        /// </summary>
        public static byte[] intTotBytes(int value)
        {
            byte[] bytes = new byte[4];
            bytes[0] = (byte)(value >> 24);
            bytes[1] = (byte)((value << 8) >> 24);
            bytes[2] = (byte)((value << 16) >> 24);
            bytes[3] = (byte)((value << 24) >> 24);
            return bytes;
        }

        /// <summary>
        /// 字节数组转换成整型
        /// </summary>
        public static int bytesToInt(byte[] bytes)
        {
            //方法一：测试通过
            //int value = bytes[0] & 0xFF;
            //value |= ((bytes[1] << 8) & 0xFF00);
            //value |= ((bytes[2] << 16) & 0xFF0000);
            //value |= (int)((bytes[3] << 24) & 0xFF000000);
            //return value;
            //方法二：待测试
            byte[] buyTemporary = new byte[4];
            buyTemporary = bytes;
            if (BitConverter.IsLittleEndian)
                Array.Reverse(buyTemporary);//反转整个一维 Array 中元素的顺序
            return BitConverter.ToInt32(buyTemporary, 0);
        }

        /// <summary>
        /// 把byte[]转化Float
        /// 低位在后，高位在前
        public float byteToFloat(byte[] bytes)
        {
            if (bytes == null)
            {
                throw new System.ArgumentException("GlobalMethods->CRC_Check(),形参为null。");
            }
            byte[] buyTemporary = new byte[4];
            try
            {
                buyTemporary[0] = (byte)(((bytes[0] & 0xFF) << 4) | bytes[1]);
                buyTemporary[1] = (byte)(((bytes[2] & 0xFF) << 4) | bytes[3]);
                buyTemporary[2] = (byte)(((bytes[4] & 0xFF) << 4) | bytes[5]);
                buyTemporary[3] = (byte)(((bytes[6] & 0xFF) << 4) | bytes[7]);
                if (BitConverter.IsLittleEndian)
                    Array.Reverse(buyTemporary);//反转整个一维 Array 中元素的顺序
                return BitConverter.ToSingle(buyTemporary, 0);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return 0;
            }
        }


        /// <summary>
        /// CRC的计算
        ///1．设置CRC寄存器，并给其赋值FFFF(hex)。
        ///2．将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或，并把结果存入CRC寄存器。
        ///3．CRC寄存器向右移一位，MSB补零，移出并检查LSB。
        ///4．如果LSB为0，重复第三步；若LSB为1，CRC寄存器与多项式码相异或。
        ///5．重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
        ///6．重复第2至第5步直到所有数据全部处理完成。
        ///7．最终CRC寄存器的内容即为CRC值。
        /// </summary>
        public static UInt32 CRC_Check(byte[] Buf, int Len)
        {
            int i, j;
            UInt32 tTemp, tCheckResult = 0xFFFF;
            if (Buf == null)
            {
                throw new System.ArgumentException("GlobalMethods->CRC_Check(),第二个参数为null。");
            }
            try
            {
                for (i = 0; i < Len - 2; i++)
                {
                    tTemp = (UInt32)Buf[i] & 0x00FF;
                    tCheckResult ^= tTemp;
                    for (j = 0; j < 8; j++)
                    {
                        if ((tCheckResult & 0x0001) == 0x0001)
                        {
                            tCheckResult >>= 1;
                            tCheckResult ^= 0xA001;
                        }
                        else
                        {
                            tCheckResult >>= 1;
                        }
                    }
                }
                return (tCheckResult);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return 0;
            }
        }

        /// <summary>
        /// 求和校验
        /// </summary>     
        public static int SumCheck(byte[] Buf, int Len)
        {
            int tSumResult = 0;
            if (Buf == null)
            {
                throw new System.ArgumentException("GlobalMethods->SumCheck(),第二个参数为null。");
            }
            try
            {
                for (int i = 1; i < Len - 1; i++)
                    tSumResult += Buf[i];
                return tSumResult;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
                return 0;
            }
        }


        /// <summary>
        /// BCC(异或和)校验
        /// </summary>
        public static byte BCC_Check(byte[] buf)//BCC校验
        {
            int tBCC_CheckResult = 0;
            int len = buf.GetUpperBound(0);
            for (int i = 0; i < len; i++)
                tBCC_CheckResult ^= buf[i];
            return (byte)(tBCC_CheckResult & 0xff);
        }

        #endregion 通用方法




    }
}
